/**
 * 
 */
package truerefactor.codesmell;

import java.util.ArrayList;
import java.util.List;

import truerefactor.graph.Accessibility;
import truerefactor.graph.AttributeNode;
import truerefactor.graph.ClassNode;
import truerefactor.graph.CodeGraph;
import truerefactor.graph.CodeNode;
import truerefactor.graph.MethodNode;
import truerefactor.metrics.NOC;
import truerefactor.refactor.Refactoring;

/**
 * @author Isaac
 */
public class RefusedBequests extends CodeSmell {

    /**
     * 
     */
    public RefusedBequests()
    {
        this.shortName = "REFBEQ";
        this.name = "Refused Bequests";
        this.description = "";
    }

    /*
     * (non-Javadoc)
     * @see
     * truerefactor.codesmell.CodeSmell#measure(truerefactor.graph.CodeGraph,
     * boolean, java.util.List)
     */
    @Override
    protected double measure(CodeGraph graph, boolean initial, List<List<Refactoring>> sequences)
    {
        int smell = 0;
        List<ClassNode> classes = graph.getClasses();        
        List<ClassNode> withChildren = new ArrayList<ClassNode>();
        
        for (ClassNode cNode : classes) {
            if (NOC.measure(cNode) > 1) {
                withChildren.add(cNode);
            }
        }
        
        for (ClassNode cNode : withChildren) {
            List<ClassNode> subclasses = cNode.getSubClasses();
            
            int attr_count = 0;
            for (CodeNode attr : cNode.getAttributes()) {
                if (attr instanceof AttributeNode) {
                    if (((AttributeNode) attr).getAccessibility().equals(Accessibility.Private))
                        continue;
                    
                    int method_count = 0;
                    for (MethodNode mNode : ((AttributeNode) attr).getOtherMethods()) {
                        if (subclasses.contains(mNode)) {
                            method_count++;
                        }
                    }
                    
                    if (method_count != 0)
                        attr_count++;
                }
            }
            
            int method_count = 0;
            for (CodeNode method : cNode.getMethods()) {
                if (method instanceof MethodNode) {
                    if (((MethodNode) method).getAccessibility().equals(Accessibility.Private))
                        continue;
                    
                    int count = 0;
                    for (MethodNode mNode : ((MethodNode) method).getOtherMethods()) {
                        if (subclasses.contains(mNode)) {
                            count++;
                        }
                    }
                    
                    if (count != 0)
                        method_count++;
                }
            }
            
            if (method_count == 0 || attr_count == 0)
                smell++;
        }
        return smell;
    }
}
